//
//  ZCoverView.swift
//  ZPlayer
//
//  Created by zuber on 2018/11/14.
//  Copyright © 2018年 zuber. All rights reserved.
//

import UIKit
import SnapKit
import MediaPlayer

protocol ZCoverViewDelegate: class {
  func zcoverViewDidClose(_ view: ZCoverView)
  func zcoverViewDidPlay(_ view: ZCoverView)
  func zcoverViewDidPause(_ view: ZCoverView)
  func zcoverView(_ view: ZCoverView, slider: ZSliderView , slideTo percent: CGFloat)
}

class ZCoverView: UIView {
  
  weak var delegate: ZCoverViewDelegate?
  
  private lazy var closeButton: UIButton = {
    let button = UIButton()
    button.backgroundColor = UIColor.coverBackgroundColor
    button.setImage(UIImage(named: "zplayer_close"), for: .normal)
    button.layer.cornerRadius = 10
    button.layer.masksToBounds = true
    button.addTarget(self, action: #selector(close), for: .touchUpInside)
    return button
  }()
  
  private lazy var bottomView: UIView = {
    let view = UIView()
    view.backgroundColor = UIColor.coverBackgroundColor
    view.layer.cornerRadius = 10
    view.layer.masksToBounds = true
    return view
  }()
  
  // 进度条
  private lazy var slider: ZSliderView = {
    let slider = ZSliderView()
    return slider
  }()
  
  // 已播放的时间
  private lazy var playedTimeLabel: UILabel = {
    let label = UILabel()
    label.textColor = UIColor.coverTextColor
    label.font = UIFont.systemFont(ofSize: 10)
    label.text = .noneTime
    return label
  }()
  
  // 总时间
  private lazy var totalTimeLabel: UILabel = {
    let label = UILabel()
    label.textColor = UIColor.coverTextColor
    label.font = UIFont.systemFont(ofSize: 10)
    label.text = .noneTime
    return label
  }()
  
  // 播放或者暂停
  private lazy var playButton: UIButton = {
    let button = UIButton()
    button.setImage(UIImage(named: "zplayer_play"), for: .normal )
    button.addTarget(self, action: #selector(playOrPause) , for: .touchUpInside )
    return button
  }()
  
  private var volumeView = MPVolumeView()
  private lazy var volumeSlider: UISlider? = {
    for view in self.volumeView.subviews {
      if let view = view as? UISlider {
        return view
      }
    }
    return nil
  }()
  
  private var toastView: ZToastView?
  
  var isSliding: Bool {
    return slider.isSliding
  }
  var isPlaying = false
  private var isAnimating = false
  private var animationDuring: TimeInterval = 0.5
  private var isMenuShow = false
  private var playerWidth: CGFloat = 0
  private var playerHeight: CGFloat = 0
  private var originalBrightness: CGFloat = 0
  private var beginBrightness: CGFloat = 0
  private var beginVolume: Float = 0
  private var originalVolume: Float = 0
  
  override init(frame: CGRect) {
    super.init(frame: frame)
    self.prepareView()
  }
  
  required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    self.prepareView()
  }
  
  override func layoutSubviews() {
    super.layoutSubviews()
    self.playerWidth = self.bounds.width
    self.playerHeight = self.bounds.height
  }
  
  func prepareView(){
    backgroundColor = UIColor.clear
    addSubview(closeButton)
    addSubview(bottomView)
    
    closeButton.snp.makeConstraints { (make) in
      make.left.equalToSuperview().offset(3)
      make.top.equalToSuperview().offset(3)
      make.width.equalTo(50)
      make.height.equalTo(40)
    }
    
    bottomView.snp.makeConstraints { (make) in
      make.left.right.bottom.equalToSuperview().inset(3)
      make.height.equalTo(90)
    }
    
    bottomView.addSubview(slider)
    bottomView.addSubview(playedTimeLabel)
    bottomView.addSubview(totalTimeLabel)
    bottomView.addSubview(playButton)
    slider.delegate = self
    slider.snp.makeConstraints { (make) in
      make.left.right.equalToSuperview().inset(10)
      make.top.equalToSuperview().offset(10)
      make.height.equalTo(20)
    }
    
    playedTimeLabel.snp.makeConstraints { (make) in
      make.left.equalTo(slider.snp.left).offset(2)
      make.top.equalTo(slider.snp.bottom).offset(5)
    }
    totalTimeLabel.snp.makeConstraints { (make) in
      make.right.equalTo(slider.snp.right).inset(2)
      make.top.equalTo(playedTimeLabel.snp.top)
    }
    playButton.snp.makeConstraints { (make) in
      make.centerX.equalToSuperview()
      make.top.equalTo(slider.snp.bottom).offset(13)
      make.width.height.equalTo(30)
    }
    
    addSubview(volumeView)
    // 放置到屏幕外的一个地方
    volumeView.frame = CGRect(x: -50, y: -50, width: 10, height: 10)
    volumeView.isHidden = false
    
    isUserInteractionEnabled = true
    addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(tapToToggleMenu)))
    
    originalVolume = self.volumeSlider?.value ?? 0
    originalBrightness = UIScreen.main.brightness
    let panSelf = UIPanGestureRecognizer(target: self, action: #selector(panGesture(_:)))
    addGestureRecognizer(panSelf)
    
    bottomView.isUserInteractionEnabled = true
    bottomView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(bottomPanToNothing)))
  }
  
  @objc
  func bottomPanToNothing(){
  }
  
  // 设置播放时间和总时间
  func setTimeValue(_ playedValue: String , totalValue: String){
    playedTimeLabel.text = playedValue
    totalTimeLabel.text = totalValue
  }
  
  func setLoadedPercent(_ percent: CGFloat){
    self.slider.setLoadedPercent(percent)
  }
  
  func setPlayedPercent(_ percent: CGFloat){
    self.slider.setPlayedPercent(percent)
  }
  
  @objc
  func close(){
    delegate?.zcoverViewDidClose(self)
  }
  
  @objc
  func playOrPause(){
    if isPlaying {
      setToPause()
      delegate?.zcoverViewDidPause(self)
    }else{
      setToPlay()
      setToShow()
      delegate?.zcoverViewDidPlay(self)
    }
  }
  
  func setToPause(){
    isPlaying = false
    playButton.setImage(UIImage(named: "zplayer_play"), for: .normal )
  }
  
  func setToPlay(){
    isPlaying = true
    playButton.setImage(UIImage(named: "zplayer_pause"), for: .normal )
  }
  
  @objc
  func tapToToggleMenu(){
    if isMenuShow {
      setToDissmiss()
    }else{
      setToShow()
    }
  }
  
  private var menuItem: DispatchWorkItem?
  func dismissLater(){
    // 3秒后
    menuItem?.cancel()
    menuItem = DispatchWorkItem { [weak self] in
      guard let `self` = self else { return }
      self.setToDissmiss()
    }
    DispatchQueue.main.asyncAfter(deadline: .now()+3, execute: menuItem!)
  }
  
  func setToDissmiss(){
    if !isMenuShow {
      return
    }
    if self.isAnimating {
      return
    }
    self.menuItem?.cancel()
    self.isMenuShow = false
    self.isAnimating = true
    UIView.animate(withDuration: animationDuring, animations: { [weak self] in
      guard let `self` = self else { return }
      self.closeButton.transform = CGAffineTransform.identity.translatedBy(x: 0, y: -100)
      self.bottomView.transform = CGAffineTransform.identity.translatedBy(x: 0, y: 150)
    }, completion: { [weak self] _ in
      guard let `self` = self else { return }
      self.isAnimating = false
    })
  }
  
  func setToShow(){
    if isMenuShow {
      self.dissmissLayerIfNeeded()
      return
    }
    if self.isAnimating {
      return
    }
    
    self.isMenuShow = true
    self.isAnimating = true
    UIView.animate(withDuration: animationDuring, animations: { [weak self] in
      guard let `self` = self else { return }
      self.closeButton.transform = CGAffineTransform.identity
      self.bottomView.transform = CGAffineTransform.identity
      }, completion: { [weak self] _ in
        guard let `self` = self else { return }
        self.isAnimating = false
        self.dissmissLayerIfNeeded()
    })
  }
  
  func dissmissLayerIfNeeded(){
    self.menuItem?.cancel()
    if self.isPlaying {
      self.dismissLater()
    }
  }
  
  var panOrigin: CGPoint = .zero
  
  @objc
  func panGesture(_ gesture: UIPanGestureRecognizer){
    let location = gesture.location(in: self)
    switch gesture.state {
    case .began:
      panOrigin = location
      beginBrightness = UIScreen.main.brightness
      beginVolume = volumeSlider?.value ?? 0
    case .changed:
      if panOrigin.x < self.playerWidth/2 {
        // 设置亮度
        let distance = location.y - panOrigin.y
        let value = beginBrightness + (distance/self.playerHeight) * -1
        let realValue = max(0,min(value,1))
        UIScreen.main.brightness = realValue
        showToast(1, value: realValue)
      }else{
        // 设置声音
        let distance = location.y - panOrigin.y
        let value = beginVolume + Float((distance/self.playerHeight) * -1)
        let realValue = max(0,min(value,1))
        volumeSlider?.value = realValue
        showToast(2, value: CGFloat(realValue))
      }
    case .ended,.failed,.cancelled:
      removeToast()
    default:
      break
    }
  }
  
  func setToOriginal(){
    menuItem?.cancel()
    UIScreen.main.brightness = self.originalBrightness
  }
  
  private var currentType = -1
  // 1 亮度 2 音量
  func showToast(_ type: Int, value: CGFloat){
    if toastView == nil {
      currentType = -1
      toastView = ZToastView()
      addSubview(toastView!)
      toastView?.snp.makeConstraints({ (make) in
        make.center.equalToSuperview()
        make.width.height.equalTo(100)
      })
    }
    if currentType != type {
      if type == 1 {
        toastView?.image = UIImage(named: "zplayer_brightness")
      }else if type == 2{
        toastView?.image = UIImage(named: "zplayer_volume")
      }
      self.currentType = type
    }
    
    toastView?.value = "\(Int(value * 100))%"
  }
  
  func removeToast(){
    toastView?.removeFromSuperview()
    toastView = nil
  }
  
}


// MARK: - ZSliderViewDelegate

extension ZCoverView: ZSliderViewDelegate {
  
  func zsliderView(_ view: ZSliderView, slideTo percent: CGFloat) {
    if self.isPlaying {
      self.dismissLater()
    }
    self.delegate?.zcoverView(self, slider: view, slideTo: percent)
  }
  
  // 停止dissmisslater 任务
  func zsliderViewBeginSlide(_ view: ZSliderView) {
    self.menuItem?.cancel()
  }
  
}


extension String {
  static let noneTime = "--:--"
  
}

